package com.opages.mvc.adapter.consul.configuration;

import com.ecwid.consul.v1.ConsulClient;
import com.opages.mvc.adapter.common.condition.annotation.ConditionalOnBean;
import com.opages.mvc.adapter.common.condition.annotation.ConditionalOnExpression;
import com.opages.mvc.adapter.common.condition.annotation.ConditionalOnMissingBean;
import com.opages.mvc.adapter.common.properties.EnableConfigurationProperties;
import com.opages.mvc.adapter.common.client.discovery.DiscoveryClient;
import com.opages.mvc.adapter.consul.discovery.ConsulDiscoveryClient;
import com.opages.mvc.adapter.consul.model.ClusterConsulClient;
import com.opages.mvc.adapter.consul.model.ConsulDiscoveryProperties;
import com.opages.mvc.adapter.consul.model.ConsulProperties;
import com.opages.mvc.adapter.consul.serviceregistry.ConsulRegistration;
import com.opages.mvc.adapter.consul.serviceregistry.ConsulServiceRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

import com.opages.mvc.adapter.consul.serviceregistry.ConsulAutoRegistration;
import org.springframework.util.StringUtils;

import javax.servlet.ServletContext;

@EnableConfigurationProperties(basePackages = "com.opages.mvc.adapter.consul")
@ConditionalOnExpression("${spring.mvc.consul.enable:false}")
public class ConsulAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean(ConsulProperties.class)
    public ClusterConsulClient clusterConsulClient(ConsulProperties consulProperties) {
        String host = consulProperties.getHost();
        ClusterConsulClient clusterConsulClient = new ClusterConsulClient();
        if(host != null && !"".equals(host)) {
            String[] mulitConsul = host.replaceAll(" ", "").split(",");
            for (String oneConsul : mulitConsul) {
                String[] ipPort = oneConsul.split(":");
                String consulHost = ipPort[0];
                if(!consulHost.startsWith("http")) {
                    consulHost = !StringUtils.isEmpty(consulProperties.getScheme())
                            ? consulProperties.getScheme() + "://" + consulHost
                            : consulHost;
                }
                int port = 8500;
                if(consulProperties.getPort() > 0) {
                    port = consulProperties.getPort();
                }
                if (ipPort.length > 1) {
                    port = Integer.parseInt(ipPort[1]);
                }
                clusterConsulClient.addConsulClient(new ConsulClient(consulHost, port));
            }
        }
        return clusterConsulClient;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnBean({ConsulDiscoveryProperties.class,ClusterConsulClient.class})
    public ConsulServiceRegistry consulServiceRegistry(ConsulDiscoveryProperties consulDiscoveryProperties, ClusterConsulClient clusterConsulClient) {
        return new ConsulServiceRegistry(consulDiscoveryProperties,clusterConsulClient);
    }

    @Bean
    @ConditionalOnBean(ConsulDiscoveryProperties.class)
    public ConsulRegistration consulRegistration(ConsulDiscoveryProperties properties, ApplicationContext context, ServletContext servletContext) {
    	return new ConsulRegistration(properties,context,servletContext.getContextPath());
    }

    @Bean
    @ConditionalOnBean({ConsulServiceRegistry.class,ConsulRegistration.class})
    public ConsulAutoRegistration consulAutoServiceRegistration(ConsulServiceRegistry consulServiceRegistry,ConsulRegistration consulRegistration) {
        return new ConsulAutoRegistration(consulServiceRegistry,consulRegistration);
    }

    @Bean
    @ConditionalOnMissingBean(DiscoveryClient.class)
    public DiscoveryClient discoveryClient() {
	    return new ConsulDiscoveryClient();
    }
}
